﻿using System;
using System.Text;
using System.Xml;
using Didaku.Attributes;
using Didaku.QEngine.Common.Interfaces;
using Didaku.QEngine.Common.Interfaces.Engine;
using Didaku.QEngine.Common.Wrapper;

namespace Didaku.QEngine.Common.Entities
{
    /// <summary>描述柜台信息的实体类
    /// </summary>
    [Serializable]
    public class Counter : ICloneable, IServiceQueueElement, IQEntity<string>
    {
        /// <summary>构造函数（给窗口编号赋值）
        /// </summary>
        public Counter()
        {
            Index = 0;
            Ranges = new WorkRangeCollection(0);
        }

        public Counter(int counterIndex)
        {
            Index = counterIndex;
        }

        /// <summary>柜台编号索引值
        /// </summary>
        [EntityColumn]
        public int Index { get; set; }

        /// <summary>实体的全局Id，默认采用网点Id+实体缩写+编号方式以保证全局的唯一性
        /// </summary>
        [EntityColumn]
        public string Id { get; set; }

        /// <summary>柜台名称
        /// </summary>
        [EntityColumn]
        public string Name { get; set; }

        /// <summary>助记编号（单网点唯一）
        /// </summary>
        [EntityColumn]
        public string Number { get; set; }

        /// <summary>营业厅分区ID
        /// </summary>
        [EntityColumn]
        public short DistrictId { get; set; }

        /// <summary>
        /// 柜台Ip地址格式如 "127.0.0.1"
        /// </summary>
        [EntityColumn]
        public string IpAddress { get; set; }

        /// <summary>对应的多个工作时间段
        /// </summary>
        /// <value>
        /// The ranges.
        /// </value>
        [EntityColumn]
        public WorkRangeCollection Ranges { get; set; }

        #region ICloneable Members

        /// <summary>浅复制
        /// </summary>
        /// <returns>object</returns>
        public object Clone()
        {
            return MemberwiseClone(); //浅复制
        }

        #endregion

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("(");
            sb.Append(Index);
            sb.Append(")");
            sb.Append(!string.IsNullOrWhiteSpace(Name) ? Name : " 柜台");
            return sb.ToString();
        }

        public XmlElement ToXml(XmlDocument doc)
        {
            XmlElement ele = doc.CreateElement("CounterInfo");
            ele.AppendChild(BuildElement(doc, "Id", Id));
            ele.AppendChild(BuildElement(doc, "Index", Index));
            ele.AppendChild(BuildElement(doc, "Name", Name));
            ele.AppendChild(BuildElement(doc, "DistrictId", DistrictId));
            ele.AppendChild(BuildElement(doc, "DisplayNumber", Number));
            return ele;
        }

        public void Parse(XmlElement element)
        {
            foreach (XmlNode node in element.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                    continue;
                if (node.Name == "Id")
                    Id = node.InnerText.Trim();
                else if (node.Name == "Index")
                    Index = int.Parse(node.InnerText.Trim());
                else if (node.Name == "Name")
                    Name = node.InnerText.Trim();
                else if (node.Name == "DistrictId")
                    DistrictId = Convert.ToInt16(node.InnerText.Trim());
                else if (node.Name == "DisplayNumber")
                    Number = node.InnerText.Trim();
                else
                {
                    throw new ArgumentException(node.InnerText);
                }
            }
        }

        protected static XmlElement BuildElement(XmlDocument doc, string localname, object value)
        {
            XmlElement ele = doc.CreateElement(localname);
            if (value != null)
                ele.InnerText = value.ToString();
            return ele;
        }

        #region Implementation of IServiceQueueElement

        /// <summary>获得本元素的ID
        /// </summary>
        /// <returns></returns>
        public string GetId()
        {
            return Id;
        }

        /// <summary>队列的元素是否是可用状态。如，业务类型可能不在工作时间范围之内。
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance is actived; otherwise, <c>false</c>.
        /// </returns>
        public bool IsActived()
        {
            return true;
        }

        #endregion
    }
}